package com.frank.pipeline.codegen;

import com.frank.pipeline.utils.CamelUnderlineTransformUtils;
import lombok.extern.slf4j.Slf4j;
import org.jooq.util.JavaWriter;

import java.io.File;


/**
 * Created by HYL on 2016/11/10.
 */
@Slf4j
public class GenerationRepo {

    private static String repoDir = "src/main/java/";
    private static String repoBasePackage = "com.frank.pipeline.repository.";

    public static void deleteRepo(String dbName, String className) {
        File file = new File((repoDir + repoBasePackage + dbName + "." + className + "Repository").replaceAll("\\.", "/") + ".java");
        log.info("delete repo => " + file.getAbsolutePath());
        file.delete();
    }

    public static void generator(String db, String table) {

        String directory = repoDir;
        String packageName = repoBasePackage;

        String dbCamel = CamelUnderlineTransformUtils.underlineToCamel(db);
        dbCamel = dbCamel.replaceFirst(dbCamel.substring(0, 1), dbCamel.substring(0, 1).toUpperCase());

        // 创建基础repo, 如果存在, 则跳过
        createBaseRepo(directory, packageName, dbCamel);

        packageName = packageName + dbCamel.toLowerCase();

        // 大写的全局table名
        String TABLE = table.toUpperCase();
        table = CamelUnderlineTransformUtils.underlineToCamel(table);
        table = table.replaceFirst(table.substring(0, 1), table.substring(0, 1).toUpperCase());

        directory += packageName.replaceAll("\\.", "/");

        // 要生成的类名
        String className = table + "Repository";

        try {
            Class.forName(packageName + "." + className);
            log.info("repo " + className + " already exist. pass ");
        } catch (ClassNotFoundException e) {
            log.info("repo " + packageName + "." + className + " not exist. generation.. ");
            log.info("generator file to => " + directory + "/" + className + ".java");

            String baseRepo = dbCamel + "BaseRepository";
            String recordName = table + "Record";

            String baseTablePackage = GenerationCodeUtil.entityBasePackage + dbCamel.toLowerCase();

            File file = new File(directory, className + ".java");
            JavaWriter out = new JavaWriter(file, "");

            out.println("/**");
            out.println(" * This class is generated by GenerationCodeUtil.");
            out.println("*/");
            out.println("package %s;", packageName);
            out.println();

            // import
            out.println("import org.apache.commons.lang3.tuple.Pair;\n" +
                    "import org.jooq.Table;\n" +
                    "import org.jooq.UpdatableRecord;\n" +
                    "import org.springframework.stereotype.Repository;\n" +
                    "\n");

            out.println("import %s;", baseTablePackage + ".tables.records." + recordName);
            out.println("import %s;", "com.frank.pipeline.repository." + baseRepo);
            out.println("import static %s;", baseTablePackage + ".Tables." + TABLE);

            // class
            out.println();
            out.println("@Repository");
            out.println("public class %s extends " + baseRepo + "<%s> {", className, recordName);

            // methods
            out.println();
            out.tab(1);
            out.override();
            out.tab(1);
            out.println("protected Pair<Class<%s>, Table<? extends UpdatableRecord>> mapping() {", recordName);
            out.tab(2);
            out.println("return Pair.of(%s.class, %s);", recordName, TABLE);
            out.tab(1);
            out.println("}");

            out.println("}");
            out.close();
        }
    }

    private static void createBaseRepo(String dir, String packageName, String dbCamel) {

        String className = dbCamel + "BaseRepository";

        try {
            Class.forName(packageName + className);
            log.info(className + " already exist. pass");
        } catch (ClassNotFoundException e) {
            log.warn("***  please configuration this new db => " + dbCamel + " in " + className + " file. ***");

            File file = new File(dir + "/" + packageName.replaceAll("\\.", "/") + className + ".java");
            JavaWriter out = new JavaWriter(file, "");

            out.println("/**");
            out.println(" * This class is generated by GenerationCodeUtil.");
            out.println("*/");

            // import
            out.println("package com.frank.pipeline.repository;\n" +
                    "\n" +
                    "import org.apache.commons.lang3.tuple.Pair;\n" +
                    "import org.jooq.DSLContext;\n" +
                    "\n" +
                    "import java.io.Serializable;\n");

            out.println();
            out.println("public abstract class %s<T extends Serializable> extends BaseRepository<T> {\n", className);

            out.tab(1);
            out.println("@Override\n" +
                    "    protected Pair<DSLContext, DSLContext> dslSelect() {\n" +
                    "        return Pair.of(null, null);\n" +
                    "    }");

            out.println("}");

            out.close();
        }
    }

}
